package three_shang.智能算法.AlgorithmCompare;

/**
 * @program: PSO
 * @description:
 * @author: DongGuoFeiFei
 * @create: 2024-10-22
 **/


import java.util.Random;

public class PSO {
    // 粒子群参数
    private static final int N = 30; // 种群规模
    private static final int DIM = 8; // 维度
    private static final int GMAX = 10000; // 最大迭代次数
    private static final double W = 0.7; // 惯性权重
    private static final double C1 = 1.5; // 个体学习因子
    private static final double C2 = 1.5; // 社会学习因子
    private static final double VMAX = 5; // 最大速度
    private static final double VMIN = -5; // 最小速度
    private static final double XMAX = 10; // 最大位置
    private static final double XMIN = -10; // 最小位置

    // 适应度函数
    private static double fitness(double[] x) {
        double denominator = Math.abs(x[0] + 1) + Math.abs(x[1]) + Math.abs(x[2] - 1) + Math.abs(x[3] + 2)
                + Math.abs(x[4] + 3) + Math.abs(x[5] - 2) + Math.abs(x[6] - 3) + 1;
        return 100 / denominator;
    }

    public static void main(String[] args) {
        Random random = new Random();

        // 初始化粒子位置和速度
        double[][] position = new double[N][DIM];
        double[][] velocity = new double[N][DIM];
        double[][] pBest = new double[N][DIM];
        double[] pBestFitness = new double[N];
        double[] gBest = new double[DIM];
        double gBestFitness = Double.MIN_VALUE;

        // 初始化粒子位置和速度
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < DIM; j++) {
                position[i][j] = XMIN + (XMAX - XMIN) * random.nextDouble();
                velocity[i][j] = VMIN + (VMAX - VMIN) * random.nextDouble();
                pBest[i][j] = position[i][j];
            }
            pBestFitness[i] = fitness(position[i]);
            if (pBestFitness[i] > gBestFitness) {
                gBestFitness = pBestFitness[i];
                System.arraycopy(pBest[i], 0, gBest, 0, DIM);
            }
        }

        // PSO迭代过程
        for (int g = 0; g < GMAX; g++) {
            for (int i = 0; i < N; i++) {
                // 更新速度和位置
                for (int j = 0; j < DIM; j++) {
                    double r1 = random.nextDouble();
                    double r2 = random.nextDouble();
                    velocity[i][j] = W * velocity[i][j]
                            + C1 * r1 * (pBest[i][j] - position[i][j])
                            + C2 * r2 * (gBest[j] - position[i][j]);

                    // 限制速度
                    if (velocity[i][j] > VMAX) velocity[i][j] = VMAX;
                    if (velocity[i][j] < VMIN) velocity[i][j] = VMIN;

                    position[i][j] += velocity[i][j];

                    // 限制位置
                    if (position[i][j] > XMAX) position[i][j] = XMAX;
                    if (position[i][j] < XMIN) position[i][j] = XMIN;
                }

                // 更新个体最优
                double fitnessValue = fitness(position[i]);
                if (fitnessValue > pBestFitness[i]) {
                    pBestFitness[i] = fitnessValue;
                    System.arraycopy(position[i], 0, pBest[i], 0, DIM);
                }

                // 更新全局最优
                if (fitnessValue > gBestFitness) {
                    gBestFitness = fitnessValue;
                    System.arraycopy(position[i], 0, gBest, 0, DIM);
                }
            }

            // 打印当前迭代的最优值
            if (g % 10 == 0) {
                System.out.println("次数: " + g + "最佳适应值: " + gBestFitness);
            }
        }
        System.out.println("次数: 10000" + "最佳适应值: " + gBestFitness);

        System.out.println("Best solution: ");
        for (int j = 0; j < DIM; j++) {
            System.out.print(gBest[j] + "、");
        }
    }
}
